///
///	@file 	capiModule.cpp
/// @brief 	C language interface module
//
/////////////////////////////////// Copyright //////////////////////////////////
//
//	@copy	default
//	
//	Copyright (c) Mbedthis Software LLC, 2003-2007. All Rights Reserved.
//	
//	This software is distributed under commercial and open source licenses.
//	You may use the GPL open source license described below or you may acquire 
//	a commercial license from Mbedthis Software. You agree to be fully bound 
//	by the terms of either license. Consult the LICENSE.TXT distributed with 
//	this software for full details.
//	
//	This software is open source; you can redistribute it and/or modify it 
//	under the terms of the GNU General Public License as published by the 
//	Free Software Foundation; either version 2 of the License, or (at your 
//	option) any later version. See the GNU General Public License for more 
//	details at: http://www.mbedthis.com/downloads/gplLicense.html
//	
//	This program is distributed WITHOUT ANY WARRANTY; without even the 
//	implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
//	
//	This GPL license does NOT permit incorporating this software into 
//	proprietary programs. If you are unable to comply with the GPL, you must
//	acquire a commercial license to use this software. Commercial licenses 
//	for this software and support services are available from Mbedthis 
//	Software at http://www.mbedthis.com 
//	
//	@end
//
/////////////////////////////////// Includes ///////////////////////////////////

#define		IN_C_API_MODULE 1

#include	"http.h"

#if BLD_FEATURE_C_API_MODULE
#if BLD_FEATURE_EGI_MODULE
#include	"http/modules/egiHandler.h"
#endif
#if BLD_FEATURE_ESP_MODULE
#include	"http/modules/espHandler.h"
#endif
#if BLD_FEATURE_C_API_CLIENT
#include	"http/client.h"
#endif
#include	"http/capi.h"

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// CapiModule //////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//	This is called when the capi module is loaded as a DLL
//

int mprCapiInit(void *handle)
{
	if (maGetHttp() == 0) {
		return MPR_ERR_NOT_INITIALIZED;
	}
	(void) new MaCapiModule(handle);
	return 0;
}

////////////////////////////////////////////////////////////////////////////////
//
//	Register us as a module. No initialization to do
//

MaCapiModule::MaCapiModule(void *handle) : MaModule("capi", handle)
{
}

////////////////////////////////////////////////////////////////////////////////

MaCapiModule::~MaCapiModule()
{
}

////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// Local Classes ////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#if BLD_FEATURE_LEGACY_API && BLD_FEATURE_ESP_MODULE
//
//	Esp class for C Esp functions
//
class CEspProc : public MaEspProc {
  private:
	MaEspCb		espCallback;
  public:
				CEspProc(char *name, MaEspCb fn);
				~CEspProc();
	int			run(MaRequest *rq, int argc, char **argv);
};

////////////////////////////////////////////////////////////////////////////////
/////////////////////////////// Support C++ Code ///////////////////////////////
////////////////////////////////////////////////////////////////////////////////

CEspProc::CEspProc(char *name, MaEspCb fn) : MaEspProc(name)
{
	espCallback = fn;
}

////////////////////////////////////////////////////////////////////////////////

CEspProc::~CEspProc()
{
}

////////////////////////////////////////////////////////////////////////////////

int CEspProc::run(MaRequest *rq, int argc, char **argv)
{
	return (*espCallback)(rq, argc, argv);
}

#endif // BLD_FEATURE_LEGACY_API && BLD_FEATURE_ESP_MODULE
////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////// C API /////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
extern "C" {

int mprCreateMpr(char *appName)
{
	(void) new Mpr(appName);
	return 0;
}

////////////////////////////////////////////////////////////////////////////////

void mprDeleteMpr()
{
	delete mprGetMpr();
}

////////////////////////////////////////////////////////////////////////////////

int mprGetFds(fd_set* readInterest, fd_set* writeInterest, 
	fd_set* exceptInterest, int *maxFd, int *lastGet)
{
	return mprGetMpr()->getFds(readInterest, writeInterest, exceptInterest,
		maxFd, lastGet);
}

////////////////////////////////////////////////////////////////////////////////

int mprGetIdleTime()
{
	return mprGetMpr()->getIdleTime();
}

////////////////////////////////////////////////////////////////////////////////

int mprIsExiting()
{
	return mprGetMpr()->isExiting();
}

////////////////////////////////////////////////////////////////////////////////

int mprRunTasks()
{
	return mprGetMpr()->runTasks();
}

////////////////////////////////////////////////////////////////////////////////

int mprRunTimers()
{
	return mprGetMpr()->runTimers();
}

////////////////////////////////////////////////////////////////////////////////

void mprServiceIO(int readyFds, fd_set* readFds, fd_set* writeFds, 
	fd_set* exceptFds)
{
	mprGetMpr()->serviceIO(readyFds, readFds, writeFds, exceptFds);
}

////////////////////////////////////////////////////////////////////////////////
#if WIN

int mprGetAsyncSelectMode()
{
	return mprGetMpr()->getAsyncSelectMode();
}

////////////////////////////////////////////////////////////////////////////////

void mprServiceWinIO(int sock, int winMask)
{
	mprGetMpr()->serviceIO(sock, winMask);
}

////////////////////////////////////////////////////////////////////////////////

void mprSetAsyncSelectMode(int on)
{
	mprGetMpr()->setAsyncSelectMode(on != 0);
}

////////////////////////////////////////////////////////////////////////////////

void mprSetHwnd(HWND appHwnd)
{
	mprGetMpr()->setHwnd(appHwnd);
}

////////////////////////////////////////////////////////////////////////////////

void mprSetSocketHwnd(HWND socketHwnd)
{
	mprGetMpr()->setSocketHwnd(socketHwnd);
}

////////////////////////////////////////////////////////////////////////////////

void mprSetSocketMessage(int  msgId)
{
	mprGetMpr()->setSocketMessage(msgId);
}
#endif
////////////////////////////////////////////////////////////////////////////////

int mprStartMpr(int startFlags)
{
	return mprGetMpr()->start(startFlags);
}

////////////////////////////////////////////////////////////////////////////////

void mprStopMpr()
{
	mprGetMpr()->stop(1);
}

////////////////////////////////////////////////////////////////////////////////

void mprServiceEvents(int loopOnce, int maxTimeout)
{
	mprGetMpr()->serviceEvents(loopOnce != 0, maxTimeout);
}

////////////////////////////////////////////////////////////////////////////////
#if BLD_FEATURE_LOG

void mprAddLogFileListener()
{
	mprGetMpr()->addListener(new MprLogToFile());
}

////////////////////////////////////////////////////////////////////////////////

void mprSetLogSpec(char *logSpec)
{
	mprGetMpr()->setLogSpec(logSpec);
}

#endif
////////////////////////////////////////////////////////////////////////////////

void mprTrace(int level, char* fmt, ...) 
{
	va_list		ap;
	char		buf[MPR_MAX_STRING];
	int			len;

	va_start(ap, fmt);
	len = mprVsprintf(buf, sizeof(buf), fmt, ap);
	mprLog(level, buf);
	va_end(ap);
}

////////////////////////////////////////////////////////////////////////////////

void mprTerminate(int graceful)
{
	mprGetMpr()->terminate(graceful == 1);
}

////////////////////////////////////////////////////////////////////////////////

void mprSetThreads(int low, int high)
{
#if BLD_FEATURE_MULTITHREAD
	if (low > 0) {
		mprGetMpr()->setMinPoolThreads(low);
	}
	if (high > 0) {
		mprGetMpr()->setMaxPoolThreads(high);
	}
#endif
}

////////////////////////////////////////////////////////////////////////////////

MaHttp *maCreateHttp()
{
	return new MaHttp();
}

////////////////////////////////////////////////////////////////////////////////

void maDeleteHttp(MaHttp *http)
{
	delete http;
}

////////////////////////////////////////////////////////////////////////////////

void maDeleteServer(MaServer *server)
{
	delete server;
}

////////////////////////////////////////////////////////////////////////////////

MaServer *maCreateServer(MaHttp *http, char *name, char *serverRoot)
{
	return new MaServer(http, name, serverRoot);
}

////////////////////////////////////////////////////////////////////////////////
#if BLD_FEATURE_CONFIG_PARSE

int maConfigureServer(MaServer *server, char *configFile)
{
	return server->configure(configFile);
}

#endif
////////////////////////////////////////////////////////////////////////////////

int maGetConfigErrorLine(MaServer *server)
{
	return server->getLine();
}

////////////////////////////////////////////////////////////////////////////////

int maStartServers(MaHttp *http)
{
	return http->start();
}

////////////////////////////////////////////////////////////////////////////////

void maStopServers(MaHttp *http)
{
	http->stop();
}

////////////////////////////////////////////////////////////////////////////////
#if BLD_FEATURE_LEGACY_API && BLD_FEATURE_ESP_MODULE

int maDefineEsp(char *name, MaEspCb fn)
{
	new CEspProc(name, fn);
	return 0;
}

#endif
////////////////////////////////////////////////////////////////////////////////
#if NOT_NEEDED

void maDone(MaRequest *rq, int code) 
{
}

#endif
////////////////////////////////////////////////////////////////////////////////

void maRequestError(MaRequest *rq, int code, char *fmt, ...) 
{
	va_list		ap;
	char		buf[MPR_MAX_STRING];

	va_start(ap, fmt);
	mprVsprintf(buf, sizeof(buf), fmt, ap);
	rq->requestError(code, buf);
	va_end(ap);
}

////////////////////////////////////////////////////////////////////////////////

char *maGetFileName(MaRequest *rq) 
{
	return rq->getFileName();
}

////////////////////////////////////////////////////////////////////////////////
#if BLD_FEATURE_COOKIE

char *maGetCookie(MaRequest *rq)
{
	return rq->getCookies();
}

////////////////////////////////////////////////////////////////////////////////

void maGetCrackedCookie(MaRequest *rq, char **name, char **value, char **path)
{
	rq->getCrackedCookie(rq->getCookies(), name, value, path);
}

////////////////////////////////////////////////////////////////////////////////

void maSetCookie(MaRequest *rq, char *name, char *value, int lifetime, 
	char *path, bool secure)
{
	rq->setCookie(name, value, lifetime, path, secure);
}

#endif
////////////////////////////////////////////////////////////////////////////////

void maSetHeader(MaRequest *rq, char *value, int allowMultiple)
{
	rq->setHeader(value, allowMultiple != 0);
}

////////////////////////////////////////////////////////////////////////////////

void maSetResponseCode(MaRequest *rq, int code)
{
	rq->setResponseCode(code);
}

////////////////////////////////////////////////////////////////////////////////

char *maGetVar(MaRequest *rq, MaEnvType objType, char *var, char *defaultValue) 
{
	return rq->getVar(objType, var, defaultValue);
}

////////////////////////////////////////////////////////////////////////////////

void maSetVar(MaRequest *rq, MaEnvType objType, char *var, char *value) 
{
	rq->setVar(objType, var, value);
}

////////////////////////////////////////////////////////////////////////////////

void maSetIntVar(MaRequest *rq, MaEnvType objType, char *var, int value) 
{
	rq->setIntVar(objType, var, value);
}

////////////////////////////////////////////////////////////////////////////////

int maGetIntVar(MaRequest *rq, MaEnvType objType, char *var, int defaultValue)
{
	return rq->getIntVar(objType, var, defaultValue);
}

////////////////////////////////////////////////////////////////////////////////

void maCreateEnvVars(MaRequest *rq, char *buf, int len)
{
	rq->createQueryVars(buf, len);
}

////////////////////////////////////////////////////////////////////////////////

void maRedirect(MaRequest *rq, int code, char *url) 
{
	rq->redirect(code, url);
	// rq->flushOutput(MPR_HTTP_FOREGROUND_FLUSH, 0);
}

////////////////////////////////////////////////////////////////////////////////

int maSetFileName(MaRequest *rq, char *fileName) 
{
	return rq->setFileName(fileName);
}

////////////////////////////////////////////////////////////////////////////////

int maWrite(MaRequest *rq, char *buf, int size) 
{
	return rq->write(buf, size);
}

////////////////////////////////////////////////////////////////////////////////

int maWriteFmt(MaRequest *rq, char* fmt, ...) 
{
	va_list		ap;
	char		buf[MPR_MAX_STRING];
	int			rc, len;

	va_start(ap, fmt);
	len = mprVsprintf(buf, sizeof(buf), fmt, ap);
	rc = rq->write(buf, len);
	va_end(ap);
	return rc;
}

////////////////////////////////////////////////////////////////////////////////

int maWriteStr(MaRequest *rq, char *s) 
{
	return rq->write(s);
}

////////////////////////////////////////////////////////////////////////////////

char *maGetUserName(MaRequest *rq)
{
    return rq->getUser();
}

////////////////////////////////////////////////////////////////////////////////

char *maGetUri(MaRequest *rq)
{
    return rq->getUri();
}

////////////////////////////////////////////////////////////////////////////////

int maIsKeepAlive(MaRequest *rq)
{
   return rq->getFlags() & MPR_HTTP_KEEP_ALIVE;
}

////////////////////////////////////////////////////////////////////////////////

int maIsEsp(MaRequest *rq)
{
   MaHandler* handler = ((MaRequest*) rq)->getCurrentHandler();
   return (strcmp(handler->getName(), "espHandler") == 0);
}

////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// Http Client ////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#if BLD_FEATURE_C_API_CLIENT

MaClient *maCreateClient()
{
	return new MaClient();
}

////////////////////////////////////////////////////////////////////////////////

void maDestroyClient(MaClient *cp)
{
	mprAssert(cp);

	delete cp;
}

////////////////////////////////////////////////////////////////////////////////

void maClientSetTimeout(MaClient *cp, int timeout)
{
	mprAssert(cp);

	cp->setTimeout(timeout);
}

////////////////////////////////////////////////////////////////////////////////

void maClientSetRetries(MaClient *cp, int count)
{
	mprAssert(cp);

	cp->setRetries(count);
}

////////////////////////////////////////////////////////////////////////////////

void maClientSetKeepAlive(MaClient *cp, int on)
{
	mprAssert(cp);

	cp->setKeepAlive(on ? true : false);
}

////////////////////////////////////////////////////////////////////////////////

char *maClientGetHeaderVar(MaClient *cp, char *key)
{
	mprAssert(cp);
	mprAssert(key);

	return cp->getHeaderVar(key);
}

////////////////////////////////////////////////////////////////////////////////

int maClientDoGetRequest(MaClient *cp, char *url)
{
	mprAssert(cp);
	mprAssert(url && *url);

	return cp->getRequest(url);
}

////////////////////////////////////////////////////////////////////////////////

int maClientDoPostRequest(MaClient *cp, char *url, char *postData, int postLen)
{
	mprAssert(cp);
	mprAssert(url && *url);

	return cp->postRequest(url, postData, postLen);
}

////////////////////////////////////////////////////////////////////////////////

int maClientDoHeadRequest(MaClient *cp, char *url)
{
	mprAssert(cp);
	mprAssert(url && *url);

	return cp->headRequest(url);
}

////////////////////////////////////////////////////////////////////////////////

int maClientDoOptionsRequest(MaClient *cp, char *url)
{
	mprAssert(cp);
	mprAssert(url && *url);

	return cp->optionsRequest(url);
}

////////////////////////////////////////////////////////////////////////////////

int maClientDoTraceRequest(MaClient *cp, char *url)
{
	mprAssert(cp);
	mprAssert(url && *url);

	return cp->traceRequest(url);
}

////////////////////////////////////////////////////////////////////////////////

int maClientGetResponseCode(MaClient *cp)
{
	mprAssert(cp);

	return cp->getResponseCode();
}

////////////////////////////////////////////////////////////////////////////////

char *maClientGetResponseContent(MaClient *cp, int *contentLen)
{
	mprAssert(cp);
	mprAssert(contentLen);

	return cp->getResponseContent(contentLen);
}

////////////////////////////////////////////////////////////////////////////////

char *maClientGetResponseHeader(MaClient *cp)
{
	mprAssert(cp);

	return cp->getResponseHeader();
}

////////////////////////////////////////////////////////////////////////////////

char *maClientGetResponseMessage(MaClient *cp)
{
	mprAssert(cp);

	return cp->getResponseMessage();
}

////////////////////////////////////////////////////////////////////////////////

int maClientGetFd(MaClient *cp)
{
	mprAssert(cp);

	return cp->getFd();
}

////////////////////////////////////////////////////////////////////////////////

char *maClientGetHost(MaClient *cp)
{
	mprAssert(cp);

	return cp->getHost();
}

////////////////////////////////////////////////////////////////////////////////

int maClientGetPort(MaClient *cp)
{
	mprAssert(cp);

	return cp->getPort();
}

////////////////////////////////////////////////////////////////////////////////

void maClientResetAuth(MaClient *cp)
{
	mprAssert(cp);

	cp->resetAuth();
}

////////////////////////////////////////////////////////////////////////////////

void maClientSetAuth(MaClient *cp, char *realm, char *user, char *password)
{
	mprAssert(cp);

	cp->setAuth(realm, user, password);
}

////////////////////////////////////////////////////////////////////////////////

void maClientSetHost(MaClient *cp, char *host)
{
	mprAssert(cp);

	cp->setHost(host);
}

////////////////////////////////////////////////////////////////////////////////

void maClientSetPort(MaClient *cp, int port)
{
	mprAssert(cp);

	cp->setPort(port);
}

////////////////////////////////////////////////////////////////////////////////

void maClientSetProxy(MaClient *cp, char *host, int port)
{
	mprAssert(cp);

	cp->setProxy(host, port);
}

////////////////////////////////////////////////////////////////////////////////

void maClientLock(MaClient *cp)
{
	mprAssert(cp);

	cp->lock();
}

////////////////////////////////////////////////////////////////////////////////

void maClientUnlock(MaClient *cp)
{
	mprAssert(cp);

	cp->unlock();
}

#endif // BLD_FEATURE_C_API_CLIENT
////////////////////////////////////////////////////////////////////////////////

char *maGetRequestUserName(MaRequest *rq)
{
    return rq->getUser();
}

////////////////////////////////////////////////////////////////////////////////

char *maGetRequestUriExt(MaRequest *rq)
{
    return rq->getUriExt();
}

////////////////////////////////////////////////////////////////////////////////

MprVar *maGetRequestVars(MaRequest *rq)
{
	return rq->getVariables();
}

////////////////////////////////////////////////////////////////////////////////
#if BLD_FEATURE_COOKIE

char *maGetRequestCookies(MaRequest *rq)
{
	return rq->getCookies();
}

#endif
////////////////////////////////////////////////////////////////////////////////

char *maGetRequestIpAddr(MaRequest *rq) 
{
	return rq->getIpAddr();
}

////////////////////////////////////////////////////////////////////////////////

char *maGetRequestMimeType(MaRequest *rq) 
{
	return rq->getRequestMimeType();
}

////////////////////////////////////////////////////////////////////////////////

char *maGetRequestUriQuery(MaRequest *rq)
{
    return rq->getQueryString();
}

////////////////////////////////////////////////////////////////////////////////

int maGetRequestPort(MaRequest *rq)
{
	return rq->getPort();
}

////////////////////////////////////////////////////////////////////////////////

MaHost *maGetDefaultHost(MaServer *server)
{
	return server->getDefaultHost();
}

////////////////////////////////////////////////////////////////////////////////

char *maGetServerRoot(MaServer *server)
{
	return server->getServerRoot();
}

////////////////////////////////////////////////////////////////////////////////

void maSetServerRoot(MaServer *server, char *root)
{
	server->setServerRoot(root);
}

////////////////////////////////////////////////////////////////////////////////

void maSetServerDefaultPage(MaServer *server, char *path, char *fileName)
{
	server->setDefaultPage(path, fileName);
}

////////////////////////////////////////////////////////////////////////////////

void maSetHostDefaultPage(MaHost *host, char *path, char *fileName)
{
	MaDir	*dir;
	char	pathBuf[MPR_MAX_FNAME];

	mprAssert(host);
	mprSprintf(pathBuf, sizeof(pathBuf), "%s/%s", host->getDocumentRoot(), 
		path);
	dir = host->findBestDir(pathBuf);
	mprAssert(dir);
	dir->setIndex(fileName);
}

////////////////////////////////////////////////////////////////////////////////

MaServer *maGetDefaultServer()
{
	return MaServer::getDefaultServer();
}

////////////////////////////////////////////////////////////////////////////////
#if BLD_FEATURE_SESSION

char *maGetSessionId(MaRequest *rq)
{
	return rq->getSessionId();
}

////////////////////////////////////////////////////////////////////////////////

void maCreateSession(MaRequest *rq, int timeout)
{
	rq->createSession(timeout);
}

////////////////////////////////////////////////////////////////////////////////

void maDestroySession(MaRequest *rq)
{
	rq->destroySession();
}

////////////////////////////////////////////////////////////////////////////////

void maSetSessionExpiryCallback(MaRequest *rq, 
	void (*callback)(void *arg), void *arg)
{
	MaSession	*sp = rq->getSession();

	/* MOB -- but what if there is not yet a session */
	if (sp) {
		sp->setExpiryCallback(callback, arg);
	}
}

#endif
////////////////////////////////////////////////////////////////////////////////

void maFlushResponse(MaRequest *rq, int background, int completeRequired)
{
	rq->flushOutput(background != 0, completeRequired != 0);
}

////////////////////////////////////////////////////////////////////////////////
} //	extern "C"

#else
void mprCapiModuleDummy() {}

#endif // BLD_FEATURE_C_API_MODULE

//
// Local variables:
// tab-width: 4
// c-basic-offset: 4
// End:
// vim: sw=4 ts=4 
//
